/*
    IceCode toolkit - maths
    Copyright (C) 2011 Alfredo 'IceCoder' Mungo

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <icecode/test/Test.hpp>
#include "../Matrix.hpp"

using namespace icecode;
using namespace icecode::test;

class MatrixTest : public Test
{
public:
  MatrixTest() : Test("Testing the Matrix class...")
  {
  }

  void run()
  {
    except_catch_begin
      maths::Matrix<2> m1({2, -1, 1, 3}), m2({1, 0, 2});
    except_catch_end(maths::Exception, "Initializer exception");

    maths::Matrix<2> m1({2, -1, 1, 3}), m2({1, 0, 2, 4}), m1_copy({2, -1, 1, 3});
    maths::Matrix<1> m3({4});

    assert(m1 == m1_copy, "== operator (1)");
    assert(!(m1 == m2), "== operator (2)");
    assert(m1 != m2, "!= operator (1)");
    assert(!(m1 != m1_copy), "!= operator (2)");

    maths::Matrix<2> m1_mul({0, -4, 7, 12});
    maths::Matrix<2> m1_res;
    m1_res = m1 * m2;
    assert(m1_mul == m1_res, "Matrix multiplication");

    maths::Matrix<2> m1_mul_scalar = {4, -2, 2, 6};
    m1_res = m1 * 2;
    assert(m1_res == m1_mul_scalar, "Scalar multiplication");

    m1_res /= 2;
    assert(m1_res == m1_copy, "Scalar division");

    m1 = m1_copy;
    assert(m1 == m1_copy, "= operator");

    maths::Matrix<2> m4 = {3, -1, 3, 7};
    m1_res = m1 + m2;
    assert(m1_res == m4, "+ operator");

    maths::Matrix<2> m_ide { 1, 0, 0, 1};
    assert(m_ide == m1.identity(), "identity() method");

    m1 += m2;
    m1_res = {2, 0, 2, 5};
    assert(m1 == m1_res, "+= operator");

    assert(m1[1][0] == 2, "[] operator");

    m1 = {1, 2, 0, 4};
    m2 = m2.transpose();

    assert(m1 == m2, "transpose() method");

  }
};
